home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / kgdb.sun3 / inflow.c.old < prev    next >
Encoding:
Text File  |  1989-08-07  |  12.0 KB  |  541 lines

  1. /* Low level interface to ptrace, for GDB when running under Unix.
  2.    Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. GDB is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GDB is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GDB; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "defs.h"
  21. #include "param.h"
  22. #include "frame.h"
  23. #include "inferior.h"
  24.  
  25. #ifdef USG
  26. #include <sys/types.h>
  27. #include <fcntl.h>
  28. #endif
  29.  
  30. #include <stdio.h>
  31. #include <sys/param.h>
  32. #include <sys/dir.h>
  33. #include <signal.h>
  34.  
  35. #ifdef HAVE_TERMIO
  36. #include <termio.h>
  37. #undef TIOCGETP
  38. #define TIOCGETP TCGETA
  39. #undef TIOCSETN
  40. #define TIOCSETN TCSETA
  41. #undef TIOCSETP
  42. #define TIOCSETP TCSETAF
  43. #define TERMINAL struct termio
  44. #else
  45. #include <sys/ioctl.h>
  46. #include <fcntl.h>
  47. #include <sgtty.h>
  48. #define TERMINAL struct sgttyb
  49. #endif
  50.  
  51. #ifdef SET_STACK_LIMIT_HUGE
  52. #include <sys/time.h>
  53. #include <sys/resource.h>
  54. extern int original_stack_limit;
  55. #endif /* SET_STACK_LIMIT_HUGE */
  56.  
  57. extern int errno;
  58.  
  59. /* Nonzero if we are debugging an attached outside process
  60.    rather than an inferior.  */
  61.  
  62. int attach_flag;
  63.  
  64.  
  65. /* Record terminal status separately for debugger and inferior.  */
  66.  
  67. static TERMINAL sg_inferior;
  68. static TERMINAL sg_ours;
  69.  
  70. static int tflags_inferior;
  71. static int tflags_ours;
  72.  
  73. #ifdef TIOCGETC
  74. static struct tchars tc_inferior;
  75. static struct tchars tc_ours;
  76. #endif
  77.  
  78. #ifdef TIOCGLTC
  79. static struct ltchars ltc_inferior;
  80. static struct ltchars ltc_ours;
  81. #endif
  82.  
  83. #ifdef TIOCLGET
  84. static int lmode_inferior;
  85. static int lmode_ours;
  86. #endif
  87.  
  88. #ifdef TIOCGPGRP
  89. static int pgrp_inferior;
  90. static int pgrp_ours;
  91. #else
  92. static int (*sigint_ours) ();
  93. static int (*sigquit_ours) ();
  94. #endif /* TIOCGPGRP */
  95. #ifndef KGDB
  96. /* Copy of inferior_io_terminal when inferior was last started.  */
  97. static char *inferior_thisrun_terminal;
  98.  
  99. static void terminal_ours_1 ();
  100.  
  101. /* Nonzero if our terminal settings are in effect.
  102.    Zero if the inferior's settings are in effect.  */
  103. static int terminal_is_ours;
  104.  
  105. /* Initialize the terminal settings we record for the inferior,
  106.    before we actually run the inferior.  */
  107.  
  108. void
  109. terminal_init_inferior ()
  110. {
  111.   if (remote_debugging)
  112.     return;
  113.  
  114.   sg_inferior = sg_ours;
  115.   tflags_inferior = tflags_ours;
  116.  
  117. #ifdef TIOCGETC
  118.   tc_inferior = tc_ours;
  119. #endif
  120.  
  121. #ifdef TIOCGLTC
  122.   ltc_inferior = ltc_ours;
  123. #endif
  124.  
  125. #ifdef TIOCLGET
  126.   lmode_inferior = lmode_ours;
  127. #endif
  128.  
  129. #ifdef TIOCGPGRP
  130.   pgrp_inferior = inferior_pid;
  131. #endif /* TIOCGPGRP */
  132.  
  133.   terminal_is_ours = 1;
  134. }
  135.  
  136. /* Put the inferior's terminal settings into effect.
  137.    This is preparation for starting or resuming the inferior.  */
  138.  
  139. void
  140. terminal_inferior ()
  141. {
  142.   if (remote_debugging)
  143.     return;
  144.  
  145.   if (terminal_is_ours)   /*  && inferior_thisrun_terminal == 0) */
  146.     {
  147.       fcntl (0, F_SETFL, tflags_inferior);
  148.       fcntl (0, F_SETFL, tflags_inferior);
  149.       ioctl (0, TIOCSETN, &sg_inferior);
  150.  
  151. #ifdef TIOCGETC
  152.       ioctl (0, TIOCSETC, &tc_inferior);
  153. #endif
  154. #ifdef TIOCGLTC
  155.       ioctl (0, TIOCSLTC, <c_inferior);
  156. #endif
  157. #ifdef TIOCLGET
  158.       ioctl (0, TIOCLSET, &lmode_inferior);
  159. #endif
  160.  
  161. #ifdef TIOCGPGRP
  162.       ioctl (0, TIOCSPGRP, &pgrp_inferior);
  163. #else
  164.       sigint_ours = (int (*) ()) signal (SIGINT, SIG_IGN);
  165.       sigquit_ours = (int (*) ()) signal (SIGQUIT, SIG_IGN);
  166. #endif /* TIOCGPGRP */
  167.     }
  168.   terminal_is_ours = 0;
  169. }
  170.  
  171. /* Put some of our terminal settings into effect,
  172.    enough to get proper results from our output,
  173.    but do not change into or out of RAW mode
  174.    so that no input is discarded.
  175.  
  176.    After doing this, either terminal_ours or terminal_inferior
  177.    should be called to get back to a normal state of affairs.  */
  178.  
  179. void
  180. terminal_ours_for_output ()
  181. {
  182.   if (remote_debugging)
  183.     return;
  184.  
  185.   terminal_ours_1 (1);
  186. }
  187.  
  188. /* Put our terminal settings into effect.
  189.    First record the inferior's terminal settings
  190.    so they can be restored properly later.  */
  191.  
  192. void
  193. terminal_ours ()
  194. {
  195.   if (remote_debugging)
  196.     return;
  197.  
  198.   terminal_ours_1 (0);
  199. }
  200.  
  201. static void
  202. terminal_ours_1 (output_only)
  203.      int output_only;
  204. {
  205. #ifdef TIOCGPGRP
  206.   /* Ignore this signal since it will happen when we try to set the pgrp.  */
  207.   int (*osigttou) ();
  208. #endif /* TIOCGPGRP */
  209.  
  210.   if (!terminal_is_ours)  /*   && inferior_thisrun_terminal == 0)  */
  211.     {
  212.       terminal_is_ours = 1;
  213.  
  214. #ifdef TIOCGPGRP
  215.       osigttou = (int (*) ()) signal (SIGTTOU, SIG_IGN);
  216.  
  217.       ioctl (0, TIOCGPGRP, &pgrp_inferior);
  218.       ioctl (0, TIOCSPGRP, &pgrp_ours);
  219.  
  220.       signal (SIGTTOU, osigttou);
  221. #else
  222.       signal (SIGINT, sigint_ours);
  223.       signal (SIGQUIT, sigquit_ours);
  224. #endif /* TIOCGPGRP */
  225.  
  226.       tflags_inferior = fcntl (0, F_GETFL, 0);
  227.       ioctl (0, TIOCGETP, &sg_inferior);
  228.  
  229. #ifdef TIOCGETC
  230.       ioctl (0, TIOCGETC, &tc_inferior);
  231. #endif
  232. #ifdef TIOCGLTC
  233.       ioctl (0, TIOCGLTC, <c_inferior);
  234. #endif
  235. #ifdef TIOCLGET
  236.       ioctl (0, TIOCLGET, &lmode_inferior);
  237. #endif
  238.     }
  239.  
  240. #ifdef HAVE_TERMIO
  241.   sg_ours.c_lflag |= ICANON;
  242.   if (output_only && !(sg_inferior.c_lflag & ICANON))
  243.     sg_ours.c_lflag &= ~ICANON;
  244. #else /* not HAVE_TERMIO */
  245.   sg_ours.sg_flags &= ~RAW & ~CBREAK;
  246.   if (output_only)
  247.     sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags;
  248. #endif /* not HAVE_TERMIO */
  249.  
  250.   fcntl (0, F_SETFL, tflags_ours);
  251.   fcntl (0, F_SETFL, tflags_ours);
  252.   ioctl (0, TIOCSETN, &sg_ours);
  253.  
  254. #ifdef TIOCGETC
  255.   ioctl (0, TIOCSETC, &tc_ours);
  256. #endif
  257. #ifdef TIOCGLTC
  258.   ioctl (0, TIOCSLTC, <c_ours);
  259. #endif
  260. #ifdef TIOCLGET
  261.   ioctl (0, TIOCLSET, &lmode_ours);
  262. #endif
  263.  
  264. #ifdef HAVE_TERMIO
  265.   sg_ours.c_lflag |= ICANON;
  266. #else /* not HAVE_TERMIO */
  267.   sg_ours.sg_flags &= ~RAW & ~CBREAK;
  268. #endif /* not HAVE_TERMIO */
  269. }
  270.  
  271. static void
  272. term_status_command ()
  273. {
  274.   register int i;
  275.  
  276.   if (remote_debugging)
  277.     {
  278.       printf_filtered ("No terminal status when remote debugging.\n");
  279.       return;
  280.     }
  281.  
  282.   printf_filtered ("Inferior's terminal status (currently saved by GDB):\n");
  283.  
  284. #ifdef HAVE_TERMIO
  285.  
  286.   printf_filtered ("fcntl flags = 0x%x, c_iflag = 0x%x, c_oflag = 0x%x,\n",
  287.       tflags_inferior, sg_inferior.c_iflag, sg_inferior.c_oflag);
  288.   printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
  289.       sg_inferior.c_cflag, sg_inferior.c_lflag, sg_inferior.c_line);
  290.   printf_filtered ("c_cc: ");
  291.   for (i = 0; (i < NCC); i += 1)
  292.     printf_filtered ("0x%x ", sg_inferior.c_cc[i]);
  293.   printf_filtered ("\n");
  294.  
  295. #else /* not HAVE_TERMIO */
  296.  
  297.   printf_filtered ("fcntl flags = 0x%x, sgttyb.sg_flags = 0x%x, owner pid = %d.\n",
  298.       tflags_inferior, sg_inferior.sg_flags, pgrp_inferior);
  299.  
  300. #endif /* not HAVE_TERMIO */
  301.  
  302. #ifdef TIOCGETC
  303.   printf_filtered ("tchars: ");
  304.   for (i = 0; i < sizeof (struct tchars); i++)
  305.     printf_filtered ("0x%x ", ((char *)&tc_inferior)[i]);
  306.   printf_filtered ("\n");
  307. #endif
  308.  
  309. #ifdef TIOCGLTC
  310.   printf_filtered ("ltchars: ");
  311.   for (i = 0; i < sizeof (struct ltchars); i++)
  312.     printf_filtered ("0x%x ", ((char *)<c_inferior)[i]);
  313.   printf_filtered ("\n");
  314.   ioctl (0, TIOCSLTC, <c_ours);
  315. #endif
  316.   
  317. #ifdef TIOCLGET
  318.   printf_filtered ("lmode:  %x\n", lmode_inferior);
  319. #endif
  320. }
  321.  
  322. static void
  323. new_tty (ttyname)
  324.      char *ttyname;
  325. {
  326.   register int tty;
  327.   register int fd;
  328.  
  329. #ifdef TIOCNOTTY
  330.   /* Disconnect the child process from our controlling terminal.  */
  331.   tty = open("/dev/tty", O_RDWR);
  332.   if (tty > 0)
  333.     {
  334.       ioctl(tty, TIOCNOTTY, 0);
  335.       close(tty);
  336.     }
  337. #endif
  338.  
  339.   /* Now open the specified new terminal.  */
  340.  
  341.   tty = open(ttyname, O_RDWR);
  342.   if (tty == -1)
  343.     _exit(1);
  344.  
  345.   /* Avoid use of dup2; doesn't exist on all systems.  */
  346.   if (tty != 0)
  347.     { close (0); dup (tty); }
  348.   if (tty != 1)
  349.     { close (1); dup (tty); }
  350.   if (tty != 2)
  351.     { close (2); dup (tty); }
  352.   if (tty > 2)
  353.     close(tty);
  354. }
  355.  
  356. /* Start an inferior process and returns its pid.
  357.    ALLARGS is a string containing shell command to run the program.
  358.    ENV is the environment vector to pass.  */
  359.  
  360. #ifndef SHELL_FILE
  361. #define SHELL_FILE "/bin/sh"
  362. #endif
  363.  
  364. int
  365. create_inferior (allargs, env)
  366.      char *allargs;
  367.      char **env;
  368. {
  369.   int pid;
  370.   char *shell_command;
  371.   extern int sys_nerr;
  372.   extern char *sys_errlist[];
  373.   extern int errno;
  374.  
  375.   /* If desired, concat something onto the front of ALLARGS.
  376.      SHELL_COMMAND is the result.  */
  377. #ifdef SHELL_COMMAND_CONCAT
  378.   shell_command = (char *) alloca (strlen (SHELL_COMMAND_CONCAT) + strlen (allargs) + 1);
  379.   strcpy (shell_command, SHELL_COMMAND_CONCAT);
  380.   strcat (shell_command, allargs);
  381. #else
  382.   shell_command = allargs;
  383. #endif
  384.  
  385.   /* exec is said to fail if the executable is open.  */
  386.   close_exec_file ();
  387. #ifdef sprite
  388.   pid = fork ();
  389. #else
  390. #if defined(USG) && !defined(HAVE_VFORK)
  391.   pid = fork ();
  392. #else
  393.   pid = vfork ();
  394. #endif
  395. #endif
  396.   if (pid < 0)
  397.     perror_with_name ("vfork");
  398.  
  399.   if (pid == 0)
  400.     {
  401. #ifdef TIOCGPGRP
  402.       /* Run inferior in a separate process group.  */
  403.       setpgrp (getpid (), getpid ());
  404. #endif /* TIOCGPGRP */
  405.  
  406. #ifdef SET_STACK_LIMIT_HUGE
  407.       /* Reset the stack limit back to what it was.  */
  408.       {
  409.     struct rlimit rlim;
  410.  
  411.     getrlimit (RLIMIT_STACK, &rlim);
  412.     rlim.rlim_cur = original_stack_limit;
  413.     setrlimit (RLIMIT_STACK, &rlim);
  414.       }
  415. #endif /* SET_STACK_LIMIT_HUGE */
  416.  
  417.  
  418.       inferior_thisrun_terminal = inferior_io_terminal;
  419.       if (inferior_io_terminal != 0)
  420.     new_tty (inferior_io_terminal);
  421.  
  422. /* Not needed on Sun, at least, and loses there
  423.    because it clobbers the superior.  */
  424. /*???      signal (SIGQUIT, SIG_DFL);
  425.       signal (SIGINT, SIG_DFL);  */
  426. #ifdef sprite
  427.     /*
  428.      * This appears to be needed on Sprite.
  429.      */
  430.     signal (SIGQUIT, SIG_DFL);
  431.     signal (SIGINT, SIG_DFL);
  432. #endif
  433.       call_ptrace (0);
  434.       execle (SHELL_FILE, "sh", "-c", shell_command, 0, env);
  435.  
  436.       fprintf (stderr, "Cannot exec %s: %s.\n", SHELL_FILE,
  437.            errno < sys_nerr ? sys_errlist[errno] : "unknown error");
  438.       fflush (stderr);
  439.       _exit (0177);
  440.     }
  441.  
  442. #ifdef CREATE_INFERIOR_HOOK
  443.   CREATE_INFERIOR_HOOK (pid);
  444. #endif  
  445.   return pid;
  446. }
  447.  
  448. /* Kill the inferior process.  Make us have no inferior.  */
  449.  
  450. static void
  451. kill_command ()
  452. {
  453.   if (remote_debugging)
  454.     return;
  455.   if (inferior_pid == 0)
  456.     error ("The program is not being run.");
  457.   if (!query ("Kill the inferior process? "))
  458.     error ("Not confirmed.");
  459.   kill_inferior ();
  460. }
  461.  
  462. void
  463. inferior_died ()
  464. {
  465.   inferior_pid = 0;
  466.   attach_flag = 0;
  467.   mark_breakpoints_out ();
  468.   select_frame ((FRAME) 0, -1);
  469.   reopen_exec_file ();
  470.   if (have_core_file_p ())
  471.     set_current_frame ( create_new_frame (read_register (FP_REGNUM),
  472.                       read_pc ()));
  473.   else
  474.     set_current_frame (0);
  475. }
  476.  
  477. static void
  478. try_writing_regs_command ()
  479. {
  480.   register int i;
  481.   register int value;
  482.   extern int errno;
  483.  
  484.   if (inferior_pid == 0)
  485.     error ("There is no inferior process now.");
  486.  
  487.   for (i = 0; ; i += 2)
  488.     {
  489.       QUIT;
  490.       errno = 0;
  491.       value = call_ptrace (3, inferior_pid, i, 0);
  492.       call_ptrace (6, inferior_pid, i, value);
  493.       if (errno == 0)
  494.     {
  495.       printf (" Succeeded with address 0x%x; value 0x%x (%d).\n",
  496.           i, value, value);
  497.     }
  498.       else if ((i & 0377) == 0)
  499.     printf (" Failed at 0x%x.\n", i);
  500.     }
  501. }
  502. #endif
  503.  
  504. void
  505. _initialize_inflow ()
  506. {
  507. #ifdef KGDB
  508.   add_com ("term-status", class_obscure, term_status_command,
  509.        "Print info on inferior's saved terminal status.");
  510.  
  511.   add_com ("try-writing-regs", class_obscure, try_writing_regs_command,
  512.        "Try writing all locations in inferior's system block.\n\
  513. Report which ones can be written.");
  514.  
  515.   add_com ("kill", class_run, kill_command,
  516.        "Kill execution of program being debugged.");
  517. #endif
  518.   inferior_pid = 0;
  519. #ifdef KGDB
  520.   ioctl (0, TIOCGETP, &sg_ours);
  521.   fcntl (0, F_GETFL, tflags_ours);
  522.  
  523. #ifdef TIOCGETC
  524.   ioctl (0, TIOCGETC, &tc_ours);
  525. #endif
  526. #ifdef TIOCGLTC
  527.   ioctl (0, TIOCGLTC, <c_ours);
  528. #endif
  529. #ifdef TIOCLGET
  530.   ioctl (0, TIOCLGET, &lmode_ours);
  531. #endif
  532.  
  533. #ifdef TIOCGPGRP
  534.   ioctl (0, TIOCGPGRP, &pgrp_ours);
  535. #endif /* TIOCGPGRP */
  536.  
  537.   terminal_is_ours = 1;
  538. #endif
  539. }
  540.  
  541.